package dao.impl.BankDaoImpl;

import common.model.Entity.bankEntity.Transaction;
import dao.BankDao.TransactionDao;
import common.util.DBUtil;

import java.sql.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * {@code TransactionDaoImpl} 是 {@link TransactionDao} 的实现类，
 * 提供了交易记录的查询与插入操作。
 * <p>
 * 使用 {@link DBUtil} 工具类获取数据库连接，通过 JDBC 完成 SQL 执行。
 * </p>
 */
public class TransactionDaoImpl implements TransactionDao {

    /**
     * 根据账户 ID、时间范围和交易类型查询交易记录。
     * <p>
     * 动态拼接 SQL 语句：
     * <ul>
     *   <li>startTime 不为空时，添加 {@code created_at >= startTime}</li>
     *   <li>endTime 不为空时，添加 {@code created_at <= endTime}</li>
     *   <li>transactionType 不为空时，添加 {@code transaction_type = transactionType}</li>
     * </ul>
     * </p>
     *
     * @param accountId       账户 ID
     * @param startTime       起始时间（可为 {@code null}）
     * @param endTime         结束时间（可为 {@code null}）
     * @param transactionType 交易类型（0: 存款, 1: 消费，可为 {@code null}）
     * @return 交易记录列表，如果没有符合条件的记录则返回空列表
     */
    @Override
    public List<Transaction> findTransactionsByAccountId(Long accountId,
                                                         LocalDateTime startTime,
                                                         LocalDateTime endTime,
                                                         Integer transactionType) {
        List<Transaction> transactions = new ArrayList<>();

        // 使用 SQL 别名对应实体类字段名
        StringBuilder sql = new StringBuilder(
                "SELECT " +
                        "id, " +
                        "user_id AS userId, " +
                        "account_id AS accountId, " +
                        "amount, " +
                        "transaction_type AS transactionType, " +
                        "description, " +
                        "status, " +
                        "created_at AS createdAt " +
                        "FROM t_transaction " +
                        "WHERE account_id = ? AND is_deleted = 0"
        );

        // 动态条件
        if (startTime != null) {
            sql.append(" AND created_at >= ?");
        }
        if (endTime != null) {
            sql.append(" AND created_at <= ?");
        }
        if (transactionType != null) {
            sql.append(" AND transaction_type = ?");
        }
        sql.append(" ORDER BY created_at DESC");

        try (Connection conn = DBUtil.getConnection();
             PreparedStatement ps = conn.prepareStatement(sql.toString())) {

            int index = 1;
            ps.setLong(index++, accountId);
            if (startTime != null) ps.setTimestamp(index++, Timestamp.valueOf(startTime));
            if (endTime != null) ps.setTimestamp(index++, Timestamp.valueOf(endTime));
            if (transactionType != null) ps.setInt(index, transactionType);

            try (ResultSet rs = ps.executeQuery()) {
                while (rs.next()) {
                    Transaction t = new Transaction();
                    t.setId(rs.getLong("id"));
                    t.setUserId(rs.getLong("userId"));
                    t.setAccountId(rs.getLong("accountId"));
                    t.setAmount(rs.getBigDecimal("amount"));
                    t.setTransactionType(rs.getInt("transactionType"));
                    t.setDescription(rs.getString("description"));
                    t.setStatus(rs.getInt("status"));
                    t.setCreatedAt(rs.getTimestamp("createdAt").toLocalDateTime());
                    transactions.add(t);
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return transactions;
    }

    /**
     * 插入一条新的交易记录。
     *
     * @param transaction 交易记录对象，不能为空
     * @return 插入是否成功，成功返回 {@code true}，否则返回 {@code false}
     */
    @Override
    public boolean insertTransaction(Transaction transaction) {
        String sql = "INSERT INTO t_transaction " +
                "(user_id, account_id, amount, transaction_type, description, status, created_at) " +
                "VALUES (?, ?, ?, ?, ?, ?, ?)";

        try (Connection conn = DBUtil.getConnection();
             PreparedStatement ps = conn.prepareStatement(sql)) {

            ps.setLong(1, transaction.getUserId());
            ps.setLong(2, transaction.getAccountId());
            ps.setBigDecimal(3, transaction.getAmount());
            ps.setInt(4, transaction.getTransactionType());
            ps.setString(5, transaction.getDescription());
            ps.setInt(6, transaction.getStatus());
            ps.setTimestamp(7, Timestamp.valueOf(transaction.getCreatedAt()));

            return ps.executeUpdate() > 0;
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return false;
    }
}
